//
//  main.m
//  OC02_实例变量可见度_方法
//
//  Created by 侯平章 on 16/2/21.
//  Copyright © 2016年 侯平章. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"
#import "CollegeStudent.h"

int main(int argc, const char * argv[]) {
    //OC方法调用
//    [接受者 消息]
#pragma mark - 知识点1.实例变量可见度
    /**
     *3种:@public ,@protected, @private
     *默认是@protected.
     *三种之间的区别:@public: 本类:可以直接访问(->),子类:可以直接访问,其他类:可以直接访问
     *                      @protected:本类:可以直接访问,子类:可以直接访问,其他类:不可以直接访问
     *                      @private:本类:可以直接访问,子类:不可以直接访问,其他类:不可以直接访问
     * 详见文件
     */

#pragma mark - 知识点2.方法
/**
 *[接受者 消息]
 *
 *接受者:类和对象.
 *消息(方法):类方法(+)和对象方法(-).
 *
 *详见文件
 */
    
#pragma mark - 知识点3.setter,getter方法
    /**
     *一个实例变量要有一对setter,getter方法.
     *setter方法目的,对实例变量赋值
     *getter方法目的,对实例变量取值
     *
     *详见文件
     */

#if 0
    //创建对象
    Person *person1 = [[Person alloc] init];
    
    //调用setter方法
    [person1 setName:@"张三"];
    //调用getter方法
    [person1 name];
    
    //定义一个字符串接收
    NSString *str = [person1 name];
    NSLog(@"%@",str);
    
    //创建Person2对象
    Person *person2 = [[Person alloc] init];
    [person2 setName:@"TOM"];
    [person2 setName:@"李四"];
    NSLog(@"%@",[person2 name]);
    
    //注意:下面的person3并没有开辟新的内存空间,只是指针指向了person2的首地址
    Person *person3 = person2;
    NSLog(@"%@",[person3 name]);
    
#pragma mark - 知识点4.继承.
    /**
     *子类继承父类所有的实例变量和方法
     *oc中,只有子类和父类两层.
     *oc中是单向继承.
     *继承有传递性.
     *
     *student类继承于Person类,collegestudent类继承于student类.
     *详见student,collegestudent类文件.
     */
    
    //创建学生对象.
    Student *stu1 = [[Student alloc] init];
    //setName方法是从父类继承下来的
    [stu1 setName:@"godV"];
    [stu1 name:@"godV" sex:@"man" age:19];
    [stu1 sayHi];
    
    //创建大学生对象
    CollegeStudent *coll1 = [[CollegeStudent alloc] init];
    [coll1 setNumber:@"93jd"];
    [coll1 setName:@"ddd"];
    
#pragma mark - 知识点5.重写父类方法(overwrite)
    /**
     *父类方法无法满足子类需求.
     *重写父类方法一般是在父类方法的基础上,添加新的代码段.
     *
     *详见Student.m文件
     */
    
    //创建一个Student对象
    Student *student1 = [[Student alloc] init];
    [student1 name:@"lsj" sex:@"man" age:30];
    [student1 setGrade:80];
    [student1 setClassRoomName:@"DLS160101"];
    [student1 sayHi];
    

#pragma mark - 知识点6.重写初始化方法.
    /**
     *Person类 重写 父类的init方法.
     *详见Person.m文件
     */
    //创建Person对象
    Person *per1 = [[Person alloc] init];
    [per1 sayHi];

    //创建Student对象
    Student *student1 = [[Student alloc] init];
    [student1 sayHi];
   
#pragma mark - 知识点7.自定义初始化方法
    
    /**
     *需求: 通过一个方法,实现了初始化,同时给某些实例变量赋值.
     *
     *详见Person.h Person.m文件.
     */
    
    //创建Person对象
    Person *per1 = [[Person alloc] initWithName:@"张三"];
    [per1 sayHi];
    Person *per2 = [[Person alloc] initWithName:@"老司机" sex:@"man" age:28];
//    [per1 initWithName:@"老司机" sex:@"man" age:28];
    [per2 sayHi];
#endif
#pragma mark -  知识点8.构造器
    /** 
     *构造器就是方法
     *+ 方法.
     *
     *详见person类文件
     */
    
    //创建对象(使用构造器方法)
    Person *per = [Person person];
    Person *per1 = [Person personWithName:@"957" sex:@"man" age:24];
    
    
    return 0;
}
